<!DOCTYPE html>
<html>
<head>
    <title>Polymer Chain Model</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="800" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // --- Helper Functions ---

        /**
         * Draws an arrow from (x1, y1) to (x2, y2).
         * @param {number} x1 - Start x-coordinate.
         * @param {number} y1 - Start y-coordinate.
         * @param {number} x2 - End x-coordinate.
         * @param {number} y2 - End y-coordinate.
         */
        function drawArrow(x1, y1, x2, y2) {
            const headlen = 10; // length of head in pixels
            const dx = x2 - x1;
            const dy = y2 - y1;
            const angle = Math.atan2(dy, dx);
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle - Math.PI / 6), y2 - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle + Math.PI / 6), y2 - headlen * Math.sin(angle + Math.PI / 6));
        }

        /**
         * Draws a molecule (circle) with a dotted pattern.
         * @param {number} x - Center x-coordinate.
         * @param {number} y - Center y-coordinate.
         * @param {number} r - Radius of the circle.
         */
        function drawDottedMolecule(x, y, r) {
            // Draw circle outline
            ctx.moveTo(x + r, y);
            ctx.arc(x, y, r, 0, 2 * Math.PI);

            // Draw dots inside
            for (let i = 0; i < 15; i++) {
                const randAngle = Math.random() * 2 * Math.PI;
                const randRadius = Math.random() * r * 0.8;
                const dotX = x + randRadius * Math.cos(randAngle);
                const dotY = y + randRadius * Math.sin(randAngle);
                ctx.moveTo(dotX, dotY);
                ctx.arc(dotX, dotY, 0.5, 0, 2 * Math.PI);
            }
        }

        /**
         * Draws a molecule (circle) with a clock face.
         * @param {number} x - Center x-coordinate.
         * @param {number} y - Center y-coordinate.
         * @param {number} r - Radius of the circle.
         */
        function drawClockMolecule(x, y, r) {
            // Draw circle outline
            ctx.moveTo(x + r, y);
            ctx.arc(x, y, r, 0, 2 * Math.PI);
            
            // Draw clock hands
            ctx.moveTo(x, y);
            ctx.lineTo(x, y - r * 0.6); // Minute hand
            ctx.moveTo(x, y);
            ctx.lineTo(x + r * 0.4, y + r * 0.2); // Hour hand

            // Draw a few dots for texture
            for (let i = 0; i < 5; i++) {
                const randAngle = Math.random() * 2 * Math.PI;
                const randRadius = Math.random() * r * 0.8;
                const dotX = x + randRadius * Math.cos(randAngle);
                const dotY = y + randRadius * Math.sin(randAngle);
                ctx.moveTo(dotX, dotY);
                ctx.arc(dotX, dotY, 0.5, 0, 2 * Math.PI);
            }
        }


        // --- Main Drawing ---

        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.font = "italic 20px serif";

        // Define layout parameters
        const r = 14;  // radius of molecule
        const d = 80;  // length of one link
        const xCoords = [100, 180, 260, 340, 420, 500, 580];
        const yCoords = [150, 220, 290];
        const startL = 50;
        const endL = 750;

        ctx.beginPath();

        // 1. Draw boundaries and L dimension line
        ctx.moveTo(startL, 100);
        ctx.lineTo(startL, 400);
        ctx.moveTo(endL, 100);
        ctx.lineTo(endL, 400);

        const yL = 380;
        ctx.moveTo(startL, yL);
        ctx.lineTo(endL, yL);
        // Ticks for L
        ctx.moveTo(startL, yL - 5);
        ctx.lineTo(startL, yL + 5);
        ctx.moveTo(endL, yL - 5);
        ctx.lineTo(endL, yL + 5);
        ctx.textAlign = 'center';
        ctx.fillText('L', (startL + endL) / 2, yL - 10);
        

        // 2. Draw the molecule configuration
        // This is a representative configuration showing branching and direction changes.
        
        // Initial chain segment
        const M0 = { x: xCoords[0], y: yCoords[1] };
        drawClockMolecule(M0.x, M0.y, r);
        
        // This molecule is drawn as a stacked pair in the original to show a choice point.
        const M1_bot = { x: xCoords[1], y: yCoords[1] };
        const M1_top = { x: xCoords[1], y: yCoords[1] - 2.5 * r };
        drawClockMolecule(M1_bot.x, M1_bot.y, r);
        drawDottedMolecule(M1_top.x, M1_top.y, r);
        drawArrow(M0.x + r, M0.y, M1_bot.x - r, M1_bot.y);

        // Top branch with a backward link
        const M2_top = { x: xCoords[2], y: M1_top.y };
        drawDottedMolecule(M2_top.x, M2_top.y, r);
        drawArrow(M2_top.x - r, M2_top.y, M1_top.x + r, M1_top.y);

        const M3_top = { x: xCoords[3], y: M1_top.y };
        drawDottedMolecule(M3_top.x, M3_top.y, r);
        drawArrow(M2_top.x + r, M2_top.y, M3_top.x - r, M3_top.y);

        // Middle branch
        const M2_mid = { x: xCoords[2], y: yCoords[1] };
        drawDottedMolecule(M2_mid.x, M2_mid.y, r);
        drawArrow(M1_bot.x + r, M1_bot.y, M2_mid.x - r, M2_mid.y);

        const M3_mid = { x: xCoords[3], y: yCoords[1]};
        drawDottedMolecule(M3_mid.x, M3_mid.y, r);
        drawArrow(M2_mid.x + r, M2_mid.y, M3_mid.x - r, M3_mid.y);

        // Lower branch, forking from M2_mid
        const M4_low = { x: xCoords[3], y: yCoords[2]};
        drawDottedMolecule(M4_low.x, M4_low.y, r);
        drawArrow(M2_mid.x + r, M2_mid.y, M4_low.x - r, M4_low.y);

        const M5_low = { x: xCoords[4], y: yCoords[2]};
        drawDottedMolecule(M5_low.x, M5_low.y, r);
        drawArrow(M4_low.x + r, M4_low.y, M5_low.x - r, M5_low.y);
        
        const M6_low = { x: xCoords[5], y: yCoords[2]};
        drawDottedMolecule(M6_low.x, M6_low.y, r);
        drawArrow(M5_low.x + r, M5_low.y, M6_low.x - r, M6_low.y);

        // Final link going off-screen
        drawArrow(M6_low.x + r, M6_low.y, M6_low.x + d - r, M6_low.y);

        // 3. Draw dimension line for d
        const y_d_dim = M1_top.y - 30;
        drawArrow(xCoords[1], y_d_dim, xCoords[2], y_d_dim);
        drawArrow(xCoords[2], y_d_dim, xCoords[1], y_d_dim); // Double-headed arrow
        ctx.textAlign = 'center';
        ctx.fillText('d', (xCoords[1] + xCoords[2]) / 2, y_d_dim - 8);

        // 4. Draw text labels
        ctx.textAlign = 'left';
        ctx.font = "italic 18px serif";
        ctx.fillText('N molecules', 550, 50);
        ctx.fillText('( N = constant )', 550, 75);
        ctx.fillText('d = length of one link', 550, 100);

        ctx.font = "18px serif";
        ctx.textAlign = 'center';
        ctx.fillText('Fig. 2.3.', canvas.width / 2, 430);

        ctx.stroke();

    </script>
</body>
</html>